﻿/*  CLR版本: 4.0.30319.18063
 * 系统时间: 2014/10/31 14:20:43
 * 创建年份: 2014
 *     作者: 程炜.Snail
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Web.Script.Serialization;
namespace Quick.Communicator
{
    public class JsonDatagramResolver : IResolver
    {
        /// <summary>
        /// json 格式解析器
        /// </summary>
        JavaScriptSerializer m_Json = new JavaScriptSerializer();
         /// <summary>
        /// 默认构造函数
        /// </summary>
        public JsonDatagramResolver()
            : base()
        { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="coder">字符编码</param>
        public JsonDatagramResolver(string coder)
            : base(coder)
        { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="coder">字符编码</param>
        public JsonDatagramResolver(System.Text.Encoding coder)
            : base(coder)
        { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="coder">字符编码</param>
        /// <param name="endTag">报文结束符</param>
        /// <param name="endTagIsHex">结束符是否是Hex格式</param>
        public JsonDatagramResolver(string coder, string endTag, bool endTagIsHex = false)
            :base(coder,endTag,endTagIsHex)
        { }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="coder">字符编码</param>
        /// <param name="endTag">报文结束符</param>
        /// <param name="endTagIsHex">结束符是否是Hex格式</param>
        public JsonDatagramResolver(System.Text.Encoding coder, string endTag, bool endTagIsHex = false)
            : base(coder, endTag, endTagIsHex)
        { }
        /// <summary>
        /// 解析报文
        /// (使用','分隔的 hexString)
        /// </summary>
        /// <param name="rawDatagram">原始数据(使用','分隔的 hexString),返回未使用的报文片断,该片断会保存在Session的Datagram对象中</param>
        /// <returns>报文数组(使用','分隔的 hexString),原始数据可能包含多个报文</returns>
        public override string[] Resolve(ref string rawDatagram)
        {
            ArrayList datagrams = new ArrayList();
            //末尾标记位置索引
            int tagIndex = -1;
            while (true)
            {
                //在进行数据分包的时候,忽略大小写进行比较
                tagIndex = FindJsonString(rawDatagram, tagIndex);
                if (tagIndex == -1)
                {
                    break;
                }
                else
                {
                    //按照末尾标记把字符串分为左右两个部分
                    string newDatagram = rawDatagram.Substring(0, tagIndex + this.HexStringEndTag.Length).Trim(base.m_HexStringTrimCharArray);
                    if (!string.IsNullOrEmpty(newDatagram))
                    {
                        //添加包含结束符的 hexString
                        datagrams.Add(newDatagram);
                    }
                    if (tagIndex + this.HexStringEndTag.Length >= rawDatagram.Length)
                    {
                        rawDatagram = string.Empty;
                        break;
                    }
                    rawDatagram = rawDatagram.Substring(tagIndex + this.HexStringEndTag.Length);
                    //从开始位置开始查找
                    tagIndex = -1;
                }
            }
            string[] results = new string[datagrams.Count];
            datagrams.CopyTo(results);
            return results;
        }
        /// <summary>
        /// 查找单个 JSON格式的字符串结束位置
        /// </summary>
        /// <param name="rawDatagram">数据内容</param>
        /// <param name="tagIndex">查找的起始位置</param>
        /// <returns>-1,无结束符</returns>
        private int FindJsonString(string rawDatagram, int tagIndex)
        {
            tagIndex = rawDatagram.IndexOf(this.HexStringEndTag, tagIndex == -1 ? 0 : tagIndex, StringComparison.OrdinalIgnoreCase);
            string newDatagram =string.Empty;
            if(tagIndex>0)
            {
                newDatagram = rawDatagram.Substring(0, tagIndex + this.HexStringEndTag.Length).Trim(base.m_HexStringTrimCharArray);
            }
            else
            {
                return -1;
            }
            try
            {
                m_Json.Serialize(base.m_Coder.Encoding.GetString(base.HexStringToByte(newDatagram)));
            }
            catch (Exception ex)
            {
                tagIndex = FindJsonString(rawDatagram, tagIndex + this.HexStringEndTag.Length);
            }
            return tagIndex;
        }
    }
}
